#ifndef SINGLETON_HPP
#define SINGLETON_HPP

namespace smeg {
    namespace tools {

////////////////////////////////////////////////////////////
/// Template class for the Singleton pattern
////////////////////////////////////////////////////////////
template <typename T>
class Singleton
{
protected:
    ////////////////////////////////////////////////////////////
    /// Default Constructor/Destructor
    ////////////////////////////////////////////////////////////
                Singleton()             {}
    virtual     ~Singleton()            {}

public:
    ////////////////////////////////////////////////////////////
    /// Get the instance of the singleton
    ///
    /// \return A pointer to the unique instance
    ///
    ////////////////////////////////////////////////////////////
    static T*   GetInstance() {
        static T s_Instance;

        return &s_Instance;
    }
};

    } // namespace tools
} // namespace smeg

#define DECLARE_SINGLETON( class_name )                                     \
    protected:                                                              \
        friend class smeg::tools::Singleton< class_name >;                  \
        class_name();                                                       \
        virtual ~class_name();

#define DECLARE_SINGLETON_EMPTY_CTOR_DTOR( class_name )                     \
    protected:                                                              \
        friend class smeg::tools::Singleton< class_name >;                  \
        class_name() {}                                                     \
        virtual ~class_name() {}

// Use it this way
/*
class your_class : public smeg::tools::Singleton< your_class > {
    DECLARE_SINGLETON( your_class )

// Your stuff here
}

    Use DECLARE_SINGLETON_EMPTY_CTOR_DTOR when you want your ctor/dtor empty
*/

#endif // SINGLETON_HPP
